package com.smallstep.hystrix.client;

import com.smallstep.hystrix.enums.HystrixKeyEnum;
import com.smallstep.hystrix.properties.FFHystrixProperties;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.ConnectionConfig;
import org.apache.http.config.SocketConfig;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;

/**
 * @author 李俊
 */
public class FFHttpClientSingleton {
    private static final FFHttpClientSingleton instance = new FFHttpClientSingleton();
    private final HttpClient httpClient;

    private FFHttpClientSingleton() {
        this.httpClient = this.bulidClient();
    }

    public static FFHttpClientSingleton getInstance() {
        return instance;
    }

    public HttpClient getHttpClient(){
        return this .httpClient;
    }

    private HttpClient bulidClient() {
        HttpClientConnectionManager httpClientConnectionManager = this.buildConnectionManager();
        RequestConfig requestConfig = this.bulidRequestConfig();
        return HttpClientBuilder.create()
                .setDefaultRequestConfig(requestConfig)
                .setConnectionManager(httpClientConnectionManager)
                .build();
    }

    private RequestConfig bulidRequestConfig() {
        RequestConfig requestConfig = RequestConfig.custom()
                        .setSocketTimeout(FFHystrixProperties.getPropertyForInteger(HystrixKeyEnum.FF_CLIENT_SOCKET_TIMEOUT))
                        .setConnectTimeout(FFHystrixProperties.getPropertyForInteger(HystrixKeyEnum.FF_CLIENT_CONNECT_TIMEOUT)).build();
        return  requestConfig;
    }

    protected HttpClientConnectionManager buildConnectionManager() {
        PoolingHttpClientConnectionManager poolingConnectionManager = new PoolingHttpClientConnectionManager();
        poolingConnectionManager.setDefaultSocketConfig(this.getConnectionManagerSocketConfig());
        poolingConnectionManager.setDefaultConnectionConfig(this.getConnectionManagerConnectionConfig());
        poolingConnectionManager.setMaxTotal(FFHystrixProperties.getPropertyForInteger(HystrixKeyEnum.FF_CLIENT_MAX_TOTAL));
        poolingConnectionManager.setDefaultMaxPerRoute(FFHystrixProperties.getPropertyForInteger(HystrixKeyEnum.FF_CLIENT_MAX_PER_ROUTE));
        return poolingConnectionManager;
    }

    protected ConnectionConfig getConnectionManagerConnectionConfig() {
        return ConnectionConfig.custom().setBufferSize(8192).setFragmentSizeHint(8192).build();
    }

    protected SocketConfig getConnectionManagerSocketConfig() {
        return SocketConfig.custom().setSoTimeout(FFHystrixProperties.getPropertyForInteger(HystrixKeyEnum.FF_CLIENT_SOCKET_TIMEOUT)).build();
    }
}
